﻿Namespace ArphoonTest
    Partial Public Class Integrity
        Public Shared Function VirtualTreeCheck(ByRef engine As Arps.Engine, ByRef errors As ULong) As Boolean
            Try
                AddLogC("Building virtual directory tree...")
                engine.BuildDirectoryTreeStructure(True)

                If Not engine.IsDirectoryTreeBuilt Then
                    AddLogC("ERROR: Cant build directory tree structure. Maybe empty?")
                    errors += 1
                End If
            Catch ex As Exception
                errors += 1
                AddLogC("ERROR: Failed to build directory tree structure. Engine Exception.")
                AddLogC("   EX: " & ex.Message)
                Return False
            End Try

            Try
                AddLogC("Building virtual file tree...")
                engine.BuildFileTreeStructure(True)

                If (Not engine.IsFileTreeBuilt) OrElse (engine.FileTree Is Nothing) OrElse (engine.FileTree.Length < 1) Then
                    AddLogC("ERROR: Cant build file tree structure. Package damaged.")
                    errors += 1
                    Return False
                End If

                If (Not engine.FileTree.Length = engine.MountedPackage.File.Length) Then
                    AddLogC("ERROR: Missing files in file tree structure. Count: " & engine.MountedPackage.File.Length - engine.FileTree.Length)
                    errors += 1
                End If
            Catch ex As Exception
                errors += 1
                AddLogC("ERROR: Failed to build file tree structure. Engine Exception.")
                AddLogC("   EX: " & ex.Message)
                Return False
            End Try

            If engine.DirectoryTree Is Nothing Then
                AddLogC("0 Directories found.")
            Else
                AddLogC(engine.DirectoryTree.Length & " Directories found.")
            End If
            AddLogC(engine.FileTree.Length & " Files found.")


            Try
                AddLogC("Checking file structure...")
                AddLogC()

                Dim i As Long
                For i = 0 To engine.FileTree.Length - 1
                    RewriteC("Checking file " & i + 1 & "/" & engine.FileTree.Length & "...", True)

                    Dim file As Arps.PackagedFileInformationCollection
                    file = engine.GetFile(engine.FileTree(i))
                    If file.FullName = "" Then
                        RewriteC("WARNING: File damaged: <" & engine.FileTree(i) & ">")
                        AddLogC("Checking file " & i + 1 & "/" & engine.FileTree.Length & "...", True)
                        errors += 1
                    End If
                Next

                ClearLog(True)
            Catch ex As Exception
                errors += 1
                AddLogC("ERROR: Failed to check file structure. Engine Exception.")
                AddLogC("   EX: " & ex.Message)
                Return False
            End Try

            Try
                If (engine.DirectoryTree Is Nothing) OrElse (engine.DirectoryTree.Length = 0) Then
                    AddLogC("Directory tree crawl test skipped. No directories inside current package.")
                    Exit Try
                End If

                AddLogC("Crawling directory tree...")
                AddLogC()

                Dim totalFiles As ULong = 0
                Dim totalDirectories As ULong = 0
                Dim lastpath As String = "\"

                If (Not _CrawlDirectoryPath(engine, errors, lastpath, totalFiles, totalDirectories)) Then
                    AddLogC("Directory Tree Crawl test FAILED!")
                    Return False
                End If

                If (totalfiles = engine.MountedPackage.File.Length) Then
                    RewriteC("Success! Directory tree structure OK.")
                Else
                    RewriteC("ERROR!: Directory tree structure damaged. File count mismatch")
                    AddLogC("     Expected: " & engine.MountedPackage.File.Length)
                    AddLogC("        Found: " & totalfiles)
                    errors += 1
                End If
                If Not (totalDirectories - 1 = engine.DirectoryTree.Length) Then
                    AddLogC("ERROR!: Directory tree structure leaf count mismatch")
                    AddLogC("        Missing or too much directory entries")
                    AddLogC("    Expected: " & engine.DirectoryTree.Length)
                    AddLogC("       Found: " & totalDirectories)
                    errors += 1
                End If
            Catch ex As Exception
                errors += 1
                AddLogC("ERROR: Failed to crawl directory structure. Engine Exception.")
                AddLogC("   EX: " & ex.Message)
                Return False
            End Try

            Return True
        End Function


        Private Shared Function _CrawlDirectoryPath(ByRef engine As Arps.Engine, ByRef errors As ULong, ByRef path As String, ByRef totalFiles As ULong, ByRef totalDirectories As ULong) As Boolean
            Dim subdirectories() As String = engine.GetDirectories(path)
            Dim subfiles() As Arps.PackagedFileInformationCollection = engine.GetFiles(path)

            If subfiles IsNot Nothing Then totalFiles += subfiles.Length
            totalDirectories += 1

            RewriteC("... [" & totalfiles & "] " & path, True)

            If (subdirectories Is Nothing) OrElse (subdirectories.Length = 0) Then Return True

            Dim i As Integer
            For i = 0 To subdirectories.Length - 1
                If Not _CrawlDirectoryPath(engine, errors, subdirectories(i), totalFiles, totalDirectories) Then Return False
            Next

            Return True
        End Function
    End Class
End Namespace

